#define _CRT_SECURE_NO_WARNINGS 1
#include"SList.h"

SLNode* CreateNode(SLNDataType x)
{
	SLNode* ret = NULL;
	ret = (SLNode*)malloc(sizeof(SLNode));
	if (ret == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	ret->val = x;
	ret->next = NULL;
	return ret;
}
void SLTPrint(SLNode* phead)
{
	assert(phead);
	SLNode* tmp = phead;
	while (tmp != NULL)
	{
		printf("%d->", tmp->val);
		tmp = tmp->next;
	}
	printf("NULL\n");
}

void SLTPushBack(SLNode** pphead, SLNDataType x)
{
	if (*pphead == NULL)
	{
		*pphead = CreateNode(x);
	}
	else
	{
		SLNode* tmp = *pphead;
		while (tmp->next != NULL)
		{
			tmp = tmp->next;
		}
		SLNode* NewNode = CreateNode(x);
		tmp->next = NewNode;
	}
}
void SLTPushFront(SLNode** pphead, SLNDataType x)
{
	SLNode* NewNode = CreateNode(x);
	SLNode* tmp = *pphead;
	NewNode->next = tmp;
	*pphead = NewNode;

}
void SLTPopBack(SLNode** pphead)
{
	assert(*pphead);
	SLNode* tmp = *pphead;
	if (tmp->next == NULL)
	{
		free(tmp);
		*pphead = NULL;
	}
	else
	{
		while (tmp->next->next != NULL)
		{
			tmp = tmp->next;
		}
		free(tmp->next);
		tmp->next = NULL;
	}


}
void SLTPopFront(SLNode** pphead)
{
	assert(*pphead);
	SLNode* tmp = *pphead;
	*pphead = tmp->next;
	free(tmp);
}

SLNode* SLTFind(SLNode* phead, SLNDataType x)
{
	assert(phead);
	SLNode* tmp = phead;
	for (; tmp != NULL; tmp = tmp->next)
	{
		if (tmp->val == x)
		{
			return tmp;
		}
	}
	return tmp;
}

void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
{
	assert(*pphead);
	SLNode* NewNode = CreateNode(x);
	if (*pphead == pos)
	{
		NewNode->next = *pphead;
		*pphead = NewNode;
	}
	else
	{
		SLNode* tmp = *pphead;
		while (tmp->next != pos)
		{
			tmp = tmp->next;
		}
		tmp->next = NewNode;
		NewNode->next = pos;
	}
}

void SLTInsertAfter(SLNode** pphead, SLNode* pos, SLNDataType x)
{
	assert(*pphead);
	pos = pos->next;
	SLTInsert(pphead, pos, x);
}

void SLTErase(SLNode** pphead, SLNode* pos)
{
	assert(*pphead&&pos);
	if (*pphead == pos)
	{
		*pphead = pos->next;
		free(pos);
	}
	else
	{
		SLNode* tmp = *pphead;
		while (tmp->next != pos)
		{
			tmp = tmp->next;
		}
		tmp->next = pos->next;
		free(pos);	
	}
}

void SLTEraseAfter(SLNode** pphead, SLNode* pos)
{


	assert(*pphead);
	if (pos == NULL)
	{
		SLTPopBack(pphead);
		return;
	}
	SLNode* tmp = *pphead;
	while (tmp->next != pos)
	{
		tmp = tmp->next;
	}
	
	pos = tmp;
	SLTErase(pphead, pos);
	
}

void SLTDestroy(SLNode** pphead)
{
	SLNode* tmp = *pphead;
	while (tmp->next != NULL)
	{
		SLNode* buf = tmp->next;
		free(tmp);
		tmp = buf;
	}
	free(tmp);
	*pphead = NULL;
}
